'use server';
import * as z from 'zod'
import {SettingsSchema} from "@/schemas";
import {currentUser} from "@/lib/auth";
import {getUserByEmail, getUserById} from "@/data/user";
import {db} from "@/lib/db";
import {generateVerificationToken} from "@/data/tokens";
import {sendVerificationEmail} from "@/lib/mail";
import bcrypt from "bcryptjs";
import {unstable_update} from "@/auth";
import {UserRole} from "@/lib/types";

// only can use async func
export const settings = async (values: z.infer<typeof SettingsSchema>) => {
    const user = await currentUser()
    if (!user) {
        return {error: "Unauthorized"}
    }

    const dbUser = await getUserById(user.id!)
    if (!dbUser) {
        return {error: "Unauthorized"}
    }

    // 第三方登录不能修改的字段
    if (user.isOAuth) {
        values.email = undefined
        values.password = undefined
        values.newPassword = undefined
        values.isTwoFactorEnable = undefined
    }

    if (values.email && values.email !== user.email) {
        const existingUser = await getUserByEmail(values.email)

        if (existingUser) {
            return {error: 'Email already in user!'}
        }

        // 生成发送验证邮件
        const verificationToken = await generateVerificationToken(values.email)
        await sendVerificationEmail(
            verificationToken.email,
            verificationToken.token
        )

        return {success: 'Verification email sent!'}
    }

    if (values.password && values.newPassword && dbUser.password) {
        const passwordsMatch = await bcrypt.compare(
            values.password,
            dbUser.password
        )

        if (!passwordsMatch) {
            return {error: 'Incorrect password!'}
        }
        values.password = await bcrypt.hash(
            values.newPassword,
            10
        )
        values.newPassword = undefined
    }

    const updatedUser = await db.user.update({
        where: {id: user.id},
        data: {
            ...values
        }
    })

    // 更新session(client端无效...)
    await unstable_update({
        user: {
            name: updatedUser.name!,
            email: updatedUser.email!,
            isTwoFactorEnable: updatedUser.isTwoFactorEnable!,
            role: updatedUser.role as UserRole,
        }
    })

    return {success: "Settings Updated!"}
}